/*
 * File Name：Mouse.java
 * Copyright：Copyright 2008-2012 CiWong.Inc. All Rights Reserved.
 * Description： Mouse.java
 * Modify By：PLA-ZJLIU
 * Modify Date：2012-12-7
 * Modify Type：Add
 */
package com.ciwong.ciwongwrite.mode;

import java.util.ArrayList;
import java.util.List;


import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;

/**
 *
 * <pre>
 * </pre>
 *
 * @author PLA-ZJLIU
 * @version ciwong v.1.0 2012-12-7
 * @since ciwong v.1.0
 */
public class TrackMouse extends TrackMove
{
    private static final float TOUCH_TOLERANCE = 0;

    protected static final String TAG = "mouse";

    public static Paint mPaint;

    public static Path mPath;

    public static float mX;

    public static float mY;

    private static int lastMouseMode = MouseMode.MOUSE_UP;

    private MouseMode mMouseMode;

    protected int panStyle = MouseMode.PAN_PAINT;

    public void setMouseMode(MouseMode mode)
    {
        mMouseMode = mode;
    }

    /**
     * 解析鼠标操作
     *
     * @param mouseActions
     * @return
     */
    public static List<TrackMouse> readTrackMouse(String mouseActions,
                                                  TrackHeader mHeader)
    {
        String[] arr = mouseActions.split(";");
        int len = arr.length;
        List<TrackMouse> trackMouses = new ArrayList<TrackMouse>();
        for (int i = 0; i < len; i++)
        {
            final TrackMouse mTrackMouse;
            MouseMode mMouseMode = reflectAction(arr[i]);
            if (mMouseMode.panStyle == MouseMode.PAN_EASER)
            {
                mTrackMouse = new TrackEaser();
                mMouseMode.color = mHeader.getBgColor();
                mMouseMode.width = TrackBase.EASER_WIDTH;
            }
            else
            {
                mTrackMouse = new TrackMouse();
            }
            mTrackMouse.mMouseMode = mMouseMode;
            trackMouses.add(mTrackMouse);
        }
        return trackMouses;
    }

    public void paint()
    {
        mPaint.setXfermode(null);
    }

    private static MouseMode reflectAction(String action)
    {
        final MouseMode mMouseMode = new MouseMode();
        String[] arr = action.replaceAll("[\\(\\)]", "").split(",");
        if (arr.length == 6)
        {
            mMouseMode.mouseDown = "1".equals(arr[0]) ? MouseMode.MOUSE_DOWN
                    : MouseMode.MOUSE_UP;
            mMouseMode.color = convertColorByIndex(Integer.parseInt(arr[1]));
            mMouseMode.width = convertWidthIndexByIndex(Integer
                    .parseInt(arr[2]));
            mMouseMode.panStyle = Integer.parseInt(arr[3]);
            mMouseMode.x = Float.parseFloat(arr[4]);
            mMouseMode.y = Float.parseFloat(arr[5]);
        }
        return mMouseMode;
    }

    public TrackMouse()
    {
        if (mPath == null)
        {
            mPath = new Path();
        }
        if (mPaint == null)
        {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(Color.TRANSPARENT);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
        }
    }

    private void createPaint(float width, int color)
    {
        mPaint.setStrokeWidth(width);
        mPaint.setColor(color);
        super.color = color;
        super.width = width;
    }

    private void start(float x, float y)
    {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;

    }

    @Override
    public void move(float x, float y)
    {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
        {
            if (mPath != null)
            {
                mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            }
            mX = x;
            mY = y;
        }
    }

    private void end(Canvas mCanvas)
    {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();

    }

    @Override
    public void touchDown(Canvas mCanvas, float x, float y)
    {
        mPaint.setStrokeWidth(width);
        mPaint.setColor(color);
        start(x, y);
        mCanvas.drawPath(mPath, mPaint);
    }

    @Override
    public void touchUp(Canvas mCanvas)
    {
        end(mCanvas);
    }

    @Override
    public void draw(Canvas mCanvas)
    {
        if (!isRecord)
        {
            if (mMouseMode == null)
            {
                return;
            }
            if (mMouseMode.mouseDown != lastMouseMode)
            {
                if (mMouseMode.mouseDown == MouseMode.MOUSE_DOWN)
                {
                    createPaint(mMouseMode.width, mMouseMode.color);
                    start(mMouseMode.x, mMouseMode.y);
                    TrackMouse.mCanvas.drawPath(mPath, mPaint);
                }
                else if (mMouseMode.mouseDown == MouseMode.MOUSE_UP)
                {
                    end(TrackMouse.mCanvas);
                }
                lastMouseMode = mMouseMode.mouseDown;
                return;
            }
            if (mMouseMode.mouseDown == MouseMode.MOUSE_DOWN)
            {
                move(mMouseMode.x, mMouseMode.y);
            }
            else if (mMouseMode.mouseDown == MouseMode.MOUSE_UP
                    || mMouseMode.mouseDown == MouseMode.MOUSE_NONE)
            {
                return;
            }
        }
        // CWLog.i(TAG, "mX:" + mX + "     mY:" + mY + "    color:" + color
        // + "   width:" + width);

        mCanvas.drawPath(mPath, mPaint);
    }

    @Override
    public String format(boolean touchDown)
    {
        StringBuilder builder = new StringBuilder();
        builder.append("(");
        builder.append(touchDown ? MoveMode.MOUSE_DOWN : MoveMode.MOUSE_UP);
        builder.append("," + convertColorIndexByColor(super.color));
        builder.append("," + convertWidthIndexByWidth((int) super.width));
        builder.append("," + panStyle);
        builder.append("," + (int) mX);
        builder.append("," + (int) mY);
        builder.append(")");
        return builder.toString();
    }

    static class MouseMode extends MoveMode
    {
        /**
         * 橡皮擦
         */
        public static final int PAN_EASER = 0;

        /**
         * 画笔
         */
        public static final int PAN_PAINT = 1;

        /**
         * 画笔颜色
         */
        public int color;

        /**
         * 画笔大小
         */
        public float width;

        /**
         * 画笔种类
         */
        public int panStyle;
    }

}
